package pl.edu.romanow.model

import net.liftweb.json.JsonAST._
import net.liftweb.common.Loggable
import com.tinkerpop.blueprints.pgm.Vertex
import GraphHelper._


/**
 * Created by IntelliJ IDEA.
 * User: jar
 * Date: 03.04.12
 * Time: 20:59
 * To change this template use File | Settings | File Templates.
 */

object JsonObjectManager extends Loggable {


  def manageFieldsNames(name: String, source: String) = (name, source) match {
    case ("id", _) => source + "Id"
    case _ => name
  }


  def mangeObject(obj: JObject, mgr: ConnectionManager, source: String, full: Boolean = true): Vertex = {

    val id = (obj \ "id") match {
      case JString(id) => id
      case JInt(id) => id.toString()
      case _ => return mgr.thrash
    }

    val vertex: Vertex = mgr.findVOrCreateById(source, id)


    obj.children.foreach(
      _ match {
        case field: JField => field.value match {
          case string: JString =>
            vertex \(manageFieldsNames(field.name, source), string.s)
          case int: JInt => vertex \(manageFieldsNames(field.name, source), int.num.toString)
          case arr: JArray => arr.arr foreach {
            el => el match {
              case obj: JObject =>
                val out = mangeObject(obj, mgr, source, false)
                mgr.createEdge(vertex, out, field.name)
              case sth => logger.error("Not known " + sth)
            }
          }
          case obj: JObject =>
            val out = mangeObject(obj, mgr, source, false)
            mgr.createEdge(vertex, out, field.name)
          case sth => logger.error("Not known " + sth)
        }
        case sth => logger.error("Not known " + sth)
      }
    )
    vertex
  }

  def manageConnection(id: String, name: String, json: JObject, mgr: ConnectionManager, source: String) {

    val parent = mgr.findVOrCreateById(source, id)

    json \ "data" match {
      case arr: JArray => arr.arr foreach {
        item => item match {
          case obj: JObject =>
            val out = mangeObject(obj, mgr, source, false)
            mgr.createEdge(parent, out, name)
          case _ => logger.error("bad data " + json)
        }
      }
      case _ => logger.error("no data in JSON! " + json)
    }
  }


  def allConnections(obj: JObject): List[String] = {

    obj \ "metadata" \ "connections" match {
      case obj: JObject => obj.children.foldLeft(List[String]()) {
        (list, ch) => ch match {
          case field: JField =>
            field.name :: list
          case _ => logger.error("Bad item in list " + obj)
          logger.info("mam conncections: " + list.mkString(", "))
          list
        }
      }
      case _ => logger.error("NO list " + obj)
      Nil
    }
  }


  def manageFriends(id: String, json: JObject, mgr: ConnectionManager, source: String): List[String] = {

    val parent = mgr.findVOrCreateById(source, id)

    var list = List[String]()

    json \ "data" match {
      case arr: JArray => arr.arr foreach {
        item => item match {
          case obj: JObject =>
            val out = mangeObject(obj, mgr, source, false)
            mgr.createEdge(parent, out, "friends")
            mgr.createEdge(out, parent, "friends")
            list = (out \ (source + "Id")) :: list
          case _ => logger.error("bad data " + json)
        }
      }
      case _ => logger.error("no data in JSON! " + json)
    }
    list
  }

  def manageMutualFriends(id: String, json: JObject, mgr: ConnectionManager, source: String) {

    val parent = mgr.findVOrCreateById(source, id)

    var list = List[String]()

    json \ "data" match {
      case arr: JArray => arr.arr foreach {
        item => item match {
          case obj: JObject =>
            val out = mangeObject(obj, mgr, source, false)
            mgr.createEdge(parent, out, "friends")
            mgr.createEdge(out, parent, "friends")
            list = (out \ (source + "Id")) :: list
          case _ => logger.error("bad data " + json)
        }
      }
      case _ => logger.error("no data in JSON! " + json)
    }
  }
}
